# 练习：请改造昨天的练习的如下题目：
# 2. 统计字符：输入一个字符串，统计大小写数字其他的个数：小试牛刀
# 3. 扩展5：求小数的每一位之和并返回结果，同时返回每一位顺序输出的数字： 返回多个值（元组）
# 7. 字符串判断，输入一个字符串，输出结果：代码复用，调试的优化，BUG和质量
# 9. 给定一个纯数字列表，进行冒泡排序：参数传值和传地址的区别

def string_stat(string):
    upper = 0
    lower = 0
    digit = 0
    other = 0

    for c in string:
        ascii = ord(c)
        if ascii >= 65 and ascii <= 90:
            upper += 1
        elif ascii >= 97 and ascii <= 122:
            lower += 1
        elif ascii in range(48, 58):
            digit += 1
        else:
            other += 1

    # print("大写：%d，小写：%d，数字：%d，其他：%d" % (upper, lower, digit, other))
    return "大写：%d，小写：%d，数字：%d，其他：%d" % (upper, lower, digit, other)



def point_sum(number):
    while int(number) >= 1:
        number /= 10

    sum = 0
    sequence = ''   # 空字符串
    while number != int(number):
        number = number * 10
        temp = int(number) % 10
        sum += temp
        # print(temp, end=' ')
        sequence = sequence + str(temp) + ' '

    # print("和为：%d" % sum)
    # print(sequence)

    # sequence = sequence.strip()   # 删除该字符串的前后的不可见字符
    sequence = sequence[0:len(sequence)-1]
    return sum, sequence             # 当return多个值时，将会以一个元组来返回



def check_number(string):
    negative = 0
    point = 0
    is_valid = True
    for c in string:
        code = ord(c)
        # if (code < 48 or code > 57) and (code != 45) and (code != 46):
        if (code < 48 and code != 45 and code != 46) or code > 57:
            is_valid = False
            break
        elif code == 45: negative += 1
        elif code == 46: point += 1

    if negative > 1: is_valid = False
    if point > 1: is_valid = False
    if negative == 1 and string[0] != '-': is_valid = False

    return is_valid




# 调用函数
# print(string_stat('Hello123你Good%^@#'))
# v1 = string_stat('Yllo3423我d%^@#')
# v2 = string_stat('YEEEEl##@lo3EEE423我d%^@#')
#
# string = input('请输入一个字符串')
# v3 = string_stat(string)
# print(v3)


# result = point_sum(120.4567)
# print(result)
# print("和为：%d，每位为：%s" % (result[0], result[1]))
#
# x, y = point_sum(120.4567)
# print("和为：%d，每位为：%s" % (x, y))   # 将返回值sum赋值给变量x，将sequence赋值给变量y



# print(check_number('12345'))
# print(check_number('123.45'))
# print(check_number('-123.45'))
# print(check_number('-12-3.45'))
# print(check_number('1.23.45'))
# print(check_number('123.45-'))
# print(check_number('12T3.45'))
# print(check_number(''))
# print(check_number('.'))
# print(check_number('-'))
# print(check_number('-.'))




# 形式参数list作为一个列表类型，为地址传递
def bubble_sort(list):
    print("形式参数List的地址是：%d" % id(list))
    for i in range(0,len(list)-1):
        for j in range(0,len(list)-i-1):
            if list[j] > list[j+1]:
                temp = list[j]
                list[j] = list[j+1]
                list[j+1] = temp
    return list



# 参数的传递：地址传递：形式参数的修改会直接影响实际参数
list1 = [11, 7, 22, 40, 33, 29, 88, 55]
print("实际参数List1的地址是: %d" % id(list1))
sorted = bubble_sort(list1)
print("返回值sorted的地址是: %d" % id(sorted))
print(list1)   # ??
print(sorted)



# arg为值传递：形式参数的修改并不会影响实际参数
def test(arg):
    arg += 10
    return arg

value = 100
print("--- %d" % id(value))
new = test(value)
print("+++ %d" % id(new))
print(value)


# 可变参数
# 1. 优先使用固定参数，如下面的a,b
# 2. 其次使用带默认值的固定参数，如下面的c,t
# 3. 再次使用一个*号的可变参数（元组）
# 4. 再次使用两个**号的可变参数（字典）
# 5. 顺序只能如此，不可逆转
print("=============可变参数==============")
def changed(a, b, x, c=50, t=60, *args, **kwargs):
    print(a+b+c)
    print(args[0])
    for i in kwargs:
        print(kwargs[i])

changed(10, 100, 200, 300, 400, 500, 600, d=100, e=200, f=300, z=400)



# 今日练习：
# 1. 利用列表实现一个用户的注册功能。
# 2. 利用已注册的用户名和密码实现登录功能。
# 基本要求：利用两个列表，一个放用户名，一个放密码，下标位置对应上。同时注册时，需要确认是否用户名已经存在，利用函数来组织代码。
# 扩展要求：把两个列表减少为一个列表，完成同样的功能。列表中的列表。
# 如果需要存第三个值，如电话号码呢？请问怎么做比较好？




